package com.bckj.fastboot.core.sql;

import com.bckj.fastboot.core.lang.func.IGetter;

import java.util.Collection;
import java.util.function.Consumer;

public interface ConditionBuilder<Children extends ConditionBuilder<Children>> {

    String getColByLambda(IGetter<?> getter);

    Children getChildren();

    Children where(String field, Object value, String opt);

    default <T> Children eq(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            eq(getter, value);
        }
        return getChildren();
    }

    default <T> Children eq(IGetter<T> getter, Object value) {
        return eq(getColByLambda(getter), value);
    }

    Children eq(String field, Object value);

    default <T> Children ne(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            ne(getter, value);
        }
        return getChildren();
    }

    default <T> Children ne(IGetter<T> getter, Object value) {
        return ne(getColByLambda(getter), value);
    }

    Children ne(String field, Object value);

    default <T> Children gt(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            gt(getter, value);
        }
        return getChildren();
    }

    default <T> Children gt(IGetter<T> getter, Object value) {
        return gt(getColByLambda(getter), value);
    }

    Children gt(String field, Object value);
    default <T> Children ge(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            ge(getter, value);
        }
        return getChildren();
    }

    default <T> Children ge(IGetter<T> getter, Object value) {
        return ge(getColByLambda(getter), value);
    }

    Children ge(String field, Object value);

    default <T> Children lt(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            lt(getter, value);
        }
        return getChildren();
    }

    default <T> Children lt(IGetter<T> getter, Object value) {
        return lt(getColByLambda(getter), value);
    }

    Children lt(String field, Object value);

    default <T> Children le(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            le(getter, value);
        }
        return getChildren();
    }

    default <T> Children le(IGetter<T> getter, Object value) {
        return le(getColByLambda(getter), value);
    }

    Children le(String field, Object value);

    default <T> Children like(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            like(getter, value);
        }
        return getChildren();
    }

    default <T> Children like(IGetter<T> getter, Object value) {
        return like(getColByLambda(getter), value);
    }

    Children like(String field, Object value);

    default  <T> Children likeLeft(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            return likeLeft(getter, value);
        }
        return getChildren();
    }

    default <T> Children likeLeft(IGetter<T> getter, Object value) {
        return likeLeft(getColByLambda(getter), value);
    }

    Children likeLeft(String field, Object value);

    default  <T> Children likeRight(boolean condition, IGetter<T> getter, Object value) {
        if (condition) {
            return likeRight(getter, value);
        }
        return getChildren();
    }

    default <T> Children likeRight(IGetter<T> getter, Object value) {
        return likeRight(getColByLambda(getter), value);
    }

    Children likeRight(String field, Object value);

    default  <T> Children between(boolean condition, IGetter<T> getter, Object val1, Object val2) {
        if (condition) {
            return between(getter, val1, val2);
        }
        return getChildren();
    }

    default <T> Children between(IGetter<T> getter, Object val1, Object val2) {
        return between(getColByLambda(getter), val1, val2);
    }

    Children between(String field, Object val1, Object val2);

    default  <T> Children in(boolean condition, IGetter<T> getter, Collection<?> coll) {
        if (condition) {
            return in(getter, coll);
        }
        return getChildren();
    }

    default <T> Children in(IGetter<T> getter, Collection<?> coll) {
        return in(getColByLambda(getter), coll);
    }

    Children in(String field, Collection<?> coll);

    default <T> Children notIn(boolean condition, IGetter<T> getter, Collection<?> coll) {
        if (condition) {
            return notIn(getter, coll);
        }
        return getChildren();
    }

    default <T> Children notIn(IGetter<T> getter, Collection<?> coll) {
        return notIn(getColByLambda(getter), coll);
    }

    Children notIn(String field, Collection<?> coll);

    default <T> Children isNull(IGetter<T>... getters) {
        return getChildren();
    }

    default Children isNull(boolean condition, String column) {
        if (condition) {
            return isNull(column);
        }
        return getChildren();
    }

    default Children isNull(String column) {
        return getChildren();
    }

    default <T> Children isNotNull(IGetter<T>... getters) {
        return getChildren();
    }

    default Children isNotNull(boolean condition, String column) {
        if (condition) {
            return isNotNull(column);
        }
        return getChildren();
    }

    default Children isNotNull(String column) {
        return getChildren();
    }

    Children and(Consumer<ConditionBuilder<?>> consumer);
    
    default Children or() {
        return getChildren();
    }

    default <T> Children makeGetters(IGetter<T>[] getters, Consumer<IGetter<T>> one, Consumer<IGetter<T>[]> many) {
        if (getters == null || getters.length == 0) {
            return getChildren();
        } else if (getters.length == 1) {
            one.accept(getters[0]);
            return getChildren();
        }
        many.accept(getters);
        return getChildren();
    }
}
